home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
Dev
/
Oberon
/
source
/
Misc
/
ConvertSwitches.mod
Wrap
Text File
|
1995-07-02
|
13KB
|
508 lines
(*************************************************************************
$RCSfile: ConvertSwitches.mod $
Description: A utility to convert the old-style compiler switches to
new-style pragmas and options.
Created by: fjc (Frank Copeland)
$Revision: 1.2 $
$Author: fjc $
$Date: 1995/01/26 01:05:15 $
Copyright © 1994-1995, Frank Copeland.
This file is part of Oberon-A.
See Oberon-A.doc for conditions of use and distribution.
*************************************************************************)
<* STANDARD- *>
MODULE ConvertSwitches;
IMPORT
SYS := SYSTEM, Kernel, Errors, rev := ConvertSwitchesRev, e := Exec,
d := Dos, f := Files, Out, wb := Workbench, i := Icon, str := Strings;
CONST
template = "FILES/A,TO/K,VERBOSE/S";
optFiles = 0;
optTo = 1;
optVerbose = 2;
optCount = 3;
VAR
rdArgs : d.RDArgsPtr;
files : e.LSTRPTR;
toDir : e.LSTRPTR;
CONST
CopyrightStr = "Copyright © 1994-1995, Frank Copeland\n";
UsageStr = "see Oberon-A.doc for conditions of use\n\n";
CONST
PathLen = 255;
TYPE
Path = ARRAY PathLen + 1 OF CHAR;
VAR
(*
These variables are global so that they may be found by the Cleanup()
procedure in the event of an abnormal exit
*)
input, (* The current input file. *)
output (* The current output file. *)
: f.File;
r, w : f.Rider;
ch : CHAR;
CONST
CR = 0DX; LF = 0AX; TAB = 09X; SP = " ";
VAR
state, line, spaces : INTEGER;
quoteChar : CHAR;
CONST
STARTLINE = 0;
WHITESPACE = 1;
COPYCHAR = 2;
LEFTBRACKET = 3;
STARTCOMMENT = 4;
COPYCOMMENT = 5;
DOLLAR = 6;
STAR = 7;
ENDCOMMENT = 8;
INSTRING = 9;
SWITCHCHAR = 10;
(*------------------------------------*)
PROCEDURE* Cleanup (VAR rc : LONGINT);
BEGIN (* Cleanup *)
IF input # NIL THEN f.Close (input) END;
IF output # NIL THEN f.Purge (output) END;
IF rdArgs # NIL THEN d.FreeArgs (rdArgs) END
END Cleanup;
(*------------------------------------*)
PROCEDURE Init ();
BEGIN (* Init *)
IF d.base.lib.version >= 37 THEN
Kernel.SetCleanup (Cleanup)
ELSE
Out.String (" !! ConvertSwitches requires OS release 2.04 or greater\n");
HALT (d.warn)
END
END Init;
(*------------------------------------*)
PROCEDURE CloneStr ( oldStr : e.LSTRPTR ) : e.LSTRPTR;
VAR newStr : e.LSTRPTR;
BEGIN (* CloneStr *)
SYS.NEW (newStr, str.Length (oldStr^) + 1);
COPY (oldStr^, newStr^);
RETURN newStr
END CloneStr;
(*------------------------------------*)
PROCEDURE GetArgs ();
VAR
argArray : ARRAY optCount OF SYS.LONGWORD;
wbArg : wb.WBArg;
wbStartup : wb.WBStartupPtr;
oldDir : d.FileLockPtr;
diskObj : wb.DiskObjectPtr;
string : e.LSTRPTR;
BEGIN (* GetArgs *)
IF Kernel.fromWorkbench THEN
ASSERT (i.base # NIL, 100);
wbStartup := SYS.VAL (wb.WBStartupPtr, Kernel.WBenchMsg);
Errors.Assert ( wbStartup.numArgs <= 2,
"ConvertSwitches -- too many arguments" );
oldDir := d.CurrentDir (wbStartup.argList[0].lock);
diskObj := i.GetDiskObject (wbStartup.argList[0].name^);
ASSERT (diskObj # NIL);
IF diskObj # NIL THEN
IF wbStartup.numArgs = 2 THEN
oldDir := d.CurrentDir (wbStartup.argList[1].lock);
string := wbStartup.argList[1].name
ELSE
string := NIL
END;
IF (string = NIL) OR (string^ = "") THEN
string := i.FindToolType (diskObj.toolTypes, "FILES")
END;
Errors.Assert (string # NIL, "ConvertSwitches -- no file specified");
files := CloneStr (string);
string := i.FindToolType (diskObj.toolTypes, "TO");
IF string # NIL THEN toDir := CloneStr (string) END;
i.FreeDiskObject (diskObj)
END;
ELSE
rdArgs := d.OldReadArgs (template, argArray, NIL);
IF rdArgs # NIL THEN
(*
** files is guaranteed to contain something, because of the /A
** toDir can be NIL
*)
files := SYS.VAL (e.LSTRPTR, argArray [optFiles]);
toDir := SYS.VAL (e.LSTRPTR, argArray [optTo]);
ELSE
ASSERT (d.PrintFault (d.IoErr(), "ReadArgs"));
HALT (d.error)
END
END;
END GetArgs;
(*------------------------------------*)
PROCEDURE MakeOutputName
(inputName : ARRAY OF CHAR; VAR outputName : ARRAY OF CHAR);
VAR filePart : e.LSTRPTR;
<*$CopyArrays-*>
BEGIN (* MakeOutputName *)
filePart := d.FilePart (inputName);
IF toDir = NIL THEN COPY ("", outputName)
ELSE COPY (toDir^, outputName)
END;
Errors.Assert
( d.AddPart (outputName, filePart^, PathLen),
"Output file name too big" )
END MakeOutputName;
(*------------------------------------*)
PROCEDURE WriteSpaces ();
BEGIN (* WriteSpaces *)
WHILE spaces > 0 DO f.Write (w, SP); DEC (spaces) END
END WriteSpaces;
(*------------------------------------*)
PROCEDURE WriteString (s : ARRAY OF CHAR);
VAR i : INTEGER; ch : CHAR;
<*$CopyArrays-*>
BEGIN (* WriteString *)
i := 0; ch := s [0];
WHILE ch # 0X DO f.Write (w, ch); INC (i); ch := s [i] END
END WriteString;
(*------------------------------------*)
PROCEDURE CopyComment ();
VAR switchChar : CHAR;
BEGIN (* CopyComment *)
state := COPYCOMMENT;
LOOP
CASE ch OF
LF :
IF state = DOLLAR THEN f.Write (w, "$") END;
IF state = SWITCHCHAR THEN
f.Write (w, "$"); f.Write (w, switchChar)
END;
f.Write (w, LF); INC (line);
IF (line MOD 10) = 0 THEN Out.Int (line, 0); Out.Char (CR) END;
state := COPYCOMMENT
|
"(" :
f.Write (w, ch); state := LEFTBRACKET
|
"*" :
f.Write (w, ch);
IF state = LEFTBRACKET THEN
f.Read (r, ch); CopyComment (); state := COPYCOMMENT
ELSE
state := STAR
END
|
")" :
f.Write (w, ch);
IF state = STAR THEN EXIT ELSE state := COPYCOMMENT END
|
"$": IF state = DOLLAR THEN f.Write (w, "$") END; state := DOLLAR
|
"+", "-", "=":
IF state = SWITCHCHAR THEN
WriteString ("<*");
CASE switchChar OF
"C" : WriteString ("$CaseChk")
|
"I" : WriteString ("$IndexChk")
|
"L" : WriteString ("$LongVars")
|
"N" : WriteString ("$NilChk")
|
"R" : WriteString ("$RangeChk")
|
"S" : WriteString ("$StackChk")
|
"T" : WriteString ("$TypeChk")
|
"V" : WriteString ("$OvflChk")
|
"Z" : WriteString ("$ClearVars")
|
"A" : WriteString ("$SaveAllRegs")
|
"D" : WriteString ("$CopyArrays")
|
"r" : WriteString ("$ReturnChk")
|
"s" : WriteString ("$SaveRegs");
|
"P" : WriteString ("STANDARD");
|
END;
IF ch = "-" THEN f.Write (w, "-")
ELSE f.Write (w, "+")
END;
WriteString ("*>")
ELSE
f.Write (w, ch)
END;
state := COPYCOMMENT
|
ELSE
IF state = DOLLAR THEN
CASE ch OF
"P", "C", "I", "L", "N", "R", "S",
"T", "V", "Z", "A", "D", "r", "s" :
switchChar := ch; state := SWITCHCHAR
|
ELSE
f.Write (w, "$"); f.Write (w, ch); state := COPYCOMMENT
END;
ELSIF state = SWITCHCHAR THEN
f.Write (w, "$"); f.Write (w, switchChar); f.Write (w, ch);
state := COPYCOMMENT
ELSE
f.Write (w, ch); state := COPYCOMMENT
END;
END;
f.Read (r, ch);
IF r.eof THEN
Out.String (" !! End of file encountered in CopyComment()\n"); EXIT
END
END
END CopyComment;
(*------------------------------------*)
PROCEDURE ChangeState ();
BEGIN (* ChangeState *)
CASE state OF
STARTLINE :
INC (line);
IF (line MOD 10) = 0 THEN Out.Int (line, 0); Out.Char (CR) END;
spaces := 0;
CASE ch OF
LF : f.Write (w, ch); state := STARTLINE
|
SP : INC (spaces); state := WHITESPACE
|
TAB : INC (spaces, 8); state := WHITESPACE
|
"(" : state := LEFTBRACKET
|
"'", '"' :
f.Write (w, ch); state := INSTRING; quoteChar := ch
|
ELSE
f.Write (w, ch); state := COPYCHAR
END;
|
WHITESPACE :
CASE ch OF
LF : f.Write (w, ch); state := STARTLINE
|
SP : INC (spaces); state := WHITESPACE
|
TAB : INC (spaces, 8); state := WHITESPACE
|
"(" : state := LEFTBRACKET
|
"'", '"' :
WriteSpaces(); f.Write (w, ch); state := INSTRING;
quoteChar := ch
|
ELSE
WriteSpaces(); f.Write (w, ch); state := COPYCHAR
END;
|
COPYCHAR :
CASE ch OF
LF : f.Write (w, ch); state := STARTLINE
|
SP : INC (spaces); state := WHITESPACE
|
TAB : INC (spaces, 8); state := WHITESPACE
|
"(" : state := LEFTBRACKET
|
"'", '"' :
f.Write (w, ch); state := INSTRING; quoteChar := ch
|
ELSE
f.Write (w, ch); state := COPYCHAR
END;
|
LEFTBRACKET :
CASE ch OF
"*" : state := STARTCOMMENT
|
LF :
WriteSpaces (); f.Write (w, "("); f.Write (w, ch);
state := STARTLINE
|
SP :
WriteSpaces (); f.Write (w, "("); spaces := 1;
state := WHITESPACE
|
TAB :
WriteSpaces (); f.Write (w, "("); spaces := 8;
state := WHITESPACE
|
"(" :
WriteSpaces (); f.Write (w, "("); state := LEFTBRACKET
|
"'", '"' :
WriteSpaces (); f.Write (w, "("); f.Write (w, ch);
state := INSTRING; quoteChar := ch
|
ELSE
WriteSpaces (); f.Write (w, "("); f.Write (w, ch);
state := COPYCHAR
END;
|
STARTCOMMENT :
WriteSpaces(); WriteString ("(*"); CopyComment(); state := ENDCOMMENT
|
ENDCOMMENT :
CASE ch OF
LF : f.Write (w, ch); state := STARTLINE
|
SP : INC (spaces); state := WHITESPACE
|
TAB : INC (spaces, 8); state := WHITESPACE
|
"(" : state := LEFTBRACKET
|
"'", '"' :
f.Write (w, ch); state := INSTRING; quoteChar := ch
|
ELSE
f.Write (w, ch); state := COPYCHAR
END;
|
INSTRING :
f.Write (w, ch); IF ch = quoteChar THEN state := COPYCHAR END
|
END
END ChangeState;
(*------------------------------------*)
PROCEDURE Strip (inputName : ARRAY OF CHAR);
VAR outputName : Path;
<*$CopyArrays-*>
BEGIN (* Strip *)
input := f.Old (inputName);
IF input # NIL THEN
MakeOutputName (inputName, outputName);
output := f.New (outputName);
IF output # NIL THEN
Out.String (" !! "); Out.String (inputName);
Out.String (" -> "); Out.String (outputName);
Out.Ln;
f.Set (r, input, 0);
f.Set (w, output, 0);
spaces := 0; state := WHITESPACE; line := 1;
WHILE ~r.eof DO
f.Read (r, ch);
ChangeState ()
END;
f.Close (input);
f.Register (output)
ELSE
f.Close (input);
Out.String (" !! Could not open "); Out.String (outputName);
Out.String (" for output"); Out.Ln;
END
ELSE
Out.String (" !! Could not open "); Out.String (inputName);
Out.String (" for input"); Out.Ln;
END;
input := NIL; output := NIL;
f.Set (r, NIL, 0); f.Set (w, NIL, 0);
Kernel.GC
END Strip;
(*------------------------------------*)
PROCEDURE Main ();
VAR
i : INTEGER; modName : ARRAY 32 OF CHAR;
myAnchor : d.AnchorPathPtr; result : LONGINT;
fileName : ARRAY 256 OF CHAR;
BEGIN (* Main *)
(* myAnchor is allocated because it must be longword aligned *)
NEW (myAnchor);
myAnchor.strlen := SHORT (LEN (myAnchor.buf));
(* Find the first file matching the pattern *)
result := d.MatchFirst (files^, myAnchor^);
WHILE result = 0 DO
(* Strip the file and get the next name. *)
Strip (myAnchor.buf);
(* Get the next matching file *)
result := d.MatchNext (myAnchor^)
END;
d.MatchEnd (myAnchor^); (* Clean up anchor data *)
END Main;
(*------------------------------------*)
BEGIN (* ConvertSwitches *)
Errors.Init;
Out.String (rev.vString);
Out.String (CopyrightStr);
Out.String (UsageStr);
Init ();
GetArgs ();
Main ();
Out.String ("\x9B\x4B !! All done\n")
END ConvertSwitches.
(*************************************************************************
$Log: ConvertSwitches.mod $
# Revision 1.2 1995/01/26 01:05:15 fjc
# - Release 1.5
#
*************************************************************************)